﻿using System;

// ReSharper disable CheckNamespace
namespace Viyi.Util
{
    /// <summary>
    /// 该类提供将<c>string</c>转换为其它数据类型的若干扩展方法。
    /// </summary>
    public static partial class StringUtil
    {
        /// <summary>
        /// 使用<see cref="System.Convert.ChangeType(object ,Type)"/>
        /// 方法将当前字符串值转换为指定的数据类型。
        /// </summary>
        /// <typeparam name="T">目标类型</typeparam>
        /// <param name="s">源字符串</param>
        /// <returns>转换失败返回指定类型的默认值，否则返回转换后的值。</returns>
        /// <remarks>相对于指定目的类型的转换来说，该转换效率较低，应尽量避免使用。</remarks>
        public static T ToValue<T>(this string s)
        {
            object v = ToValue(s, typeof(T), default(T));
            return v == null ? default(T) : (T) v;
        }

        /// <summary>
        /// 使用<see cref="System.Convert.ChangeType(object ,Type)"/>
        /// 方法将当前字符串值转换为指定的数据类型。
        /// </summary>
        /// <typeparam name="T">目标类型</typeparam>
        /// <param name="s">源字符串</param>
        /// <param name="defaultValue">转换失败时使用的默认值</param>
        /// <returns>转换失败返回传入的默认值，否则返回转换后的值。</returns>
        /// <remarks>相对于指定目的类型的转换来说，该转换效率较低，应尽量避免使用。</remarks>
        public static T ToValue<T>(this string s, T defaultValue)
        {
            object v = ToValue(s, typeof(T), defaultValue);
            return v == null ? defaultValue : (T) v;
        }

        /// <summary>
        /// 使用<see cref="System.Convert.ChangeType(object ,Type)"/>
        /// 方法将当前字符串值转换为指定的数据类型。
        /// </summary>
        /// <param name="s">源字符串</param>
        /// <param name="type">目标类型</param>
        /// <returns>转换失败返回null，否则返回转换后的值。</returns>
        /// <remarks>相对于指定目的类型的转换来说，该转换效率较低，应尽量避免使用。</remarks>
        public static object ToValue(this string s, Type type)
        {
            return ToValue(s, type, null);
        }

        /// <summary>
        /// 使用<see cref="System.Convert.ChangeType(object ,Type)"/>
        /// 方法将当前字符串值转换为指定的数据类型。
        /// </summary>
        /// <param name="s">源字符串</param>
        /// <param name="type">目标类型</param>
        /// <param name="defaultValue">转换失败时使用的默认值</param>
        /// <returns>转换失败返回传入的默认值（object类型引用），否则返回转换后的值。</returns>
        /// <remarks>相对于指定目的类型的转换来说，该转换效率较低，应尽量避免使用。</remarks>
        public static object ToValue(this string s, Type type, object defaultValue)
        {
            if (s == null) { return defaultValue; }
            try { return Convert.ChangeType(s, type); }
            catch { return defaultValue; }
        }

        /// <remark>
        /// 注意：如果 s 为 null，仍然返回 null
        /// </remark>
        public static string EmptyAs(this string s, string value)
        {
            return s == string.Empty ? value : s;
        }

        public static string EmptyAsNull(this string s)
        {
            return string.IsNullOrEmpty(s) ? null : s;
        }

        public static string NullOrEmptyAs(this string s, string value)
        {
            return string.IsNullOrEmpty(s) ? value : s;
        }

        /// <remark>
        /// 注意：如果 s 为 null，仍然返回 null
        /// </remark>
        public static string WhiteSpaceAs(this string s, string value)
        {
            return s == null
                ? null
                : string.IsNullOrWhiteSpace(s) ? value : s;
        }

        public static string WhiteSpaceAsNull(this string s)
        {
            return string.IsNullOrWhiteSpace(s) ? null : s;
        }

        public static string NullOrWhiteSpaceAs(this string s, string value)
        {
            return string.IsNullOrWhiteSpace(s) ? value : s;
        }
    }
}
